package com.flyme.module.order.provider.service.impl;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.flyme.common.core.model.ResultBody;
import com.flyme.common.core.model.query.CriteriaQuery;
import com.flyme.common.core.model.query.PagerInfo;
import com.flyme.common.core.model.query.PqGrid;
import com.flyme.common.core.utils.DateUtils;
import com.flyme.common.core.utils.ObjectUtils;
import com.flyme.core.base.supper.entity.EntityMap;
import com.flyme.core.base.supper.service.impl.BaseServiceImpl;
import com.flyme.module.order.client.entity.Order;
import com.flyme.module.order.client.entity.OrderInfo;
import com.flyme.module.order.client.enums.OrderStatusEnum;
import com.flyme.module.order.client.enums.OrderTypeEnum;
import com.flyme.module.order.client.enums.PayStatusEnum;
import com.flyme.module.order.client.enums.PayTypeEnum;
import com.flyme.module.order.provider.mapper.OrderMapper;
import com.flyme.module.order.provider.service.OrderService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author: flyme
 * @date: 2018/3/7 15:27
 * @desc: 订单管理接口实现
 */
@Service
public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, Order> implements OrderService{

    @Override
    public Boolean update(Order order) {
        return saveOrUpdate(order);
    }

    @Override
    public ResultBody delByIds(String[] ids) {
        remove(q().in("id", ids));
        return ResultBody.success("刪除成功");
    }


    /**
     * 根据第三方流水号查询订单
     */
    public Order findByNo(String outTradeNo) {
        return getOne(q().eq(true, "outTradeNo", outTradeNo), false);
    }

    /**
     * 更新第三方流水号
     */
    @Override
    public Boolean editOrder(String outTradeNo, String orderId, String payType) {
        UpdateWrapper order = new UpdateWrapper();
        return update(new Order(), order.set(true, "outTradeNo", outTradeNo).set(true, "payType", payType).eq(true, "id", orderId));
    }

    public ResultBody createOrder(OrderInfo orderInfo) {
        EntityMap map = new EntityMap();
        String handlerName = orderInfo.getHandlerName();
        Long targetId = orderInfo.getTargetId();
        Order order = new Order();
        order.setOrderAmount(orderInfo.getAmount());
        order.setTargetId(targetId);
        order.setOrderEntity(OrderTypeEnum.getEnum(handlerName));//所属业务模块
        order.setOrderTitle(OrderTypeEnum.getText(handlerName));
        order.setOrderBody(OrderTypeEnum.getText(handlerName));
        order.setOrderBody(orderInfo.getBody());
        order.setLinkName(orderInfo.getLinkName());
        order.setCompany(orderInfo.getCompany());
        order.setLinkPhone(orderInfo.getLinkPhone());
        //order.setOrderNo(serialNoService.updateSerialNo("T", "Order"));
        order.setOrderStatus(OrderStatusEnum.unpaid);
        order.setPayStatus(PayStatusEnum.NOPAY);
        order.setOutTradeNo(UUID.randomUUID().toString().replace("-", ""));
        order.setUserId(orderInfo.getUserId());
        order.setIsDel(2);
        order.setInviteId(orderInfo.getInviteId());
        order.setIsInvoice(2);
        order.setApplyType(orderInfo.getApplyType());
        order.setOrderImage(orderInfo.getOrderImg());
        order.setCloseDate(DateUtil.formatDateTime(DateUtil.offsetMinute(DateUtil.date(), 15)));
        BigDecimal amount = ObjectUtils.gertBigDecimal(order.getOrderAmount(), "0");
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {//当订单金额小于0时
            return ResultBody.failed("订单金额必须大于0！");
        }
        boolean a = saveOrUpdate(order);
        if (a) {
            map.put("orderId", order.getId());
            return ResultBody.success("订单创建成功", map);
        }
        return ResultBody.failed("订单创建失败！");
    }

    /**
     * 网站查询用户订单2
     */
    public PqGrid selectByAccount2Web(Long accountId, String orderStatus, PagerInfo pagerInfo) {
        CriteriaQuery queryWrapper = new CriteriaQuery<EntityMap>(pagerInfo);
        queryWrapper.select("o.id orderId,o.orderAmount,o.payType,o.orderBody courseTitle,o.orderImage courseImage," +
            "o.isInvoice,o.orderNo,o.orderStatus,o.createTime,o.payStatus,o.targetId,o.orderEntity,o.applyType,vipprice.iosId");
        queryWrapper.eq("userId", accountId);
        queryWrapper.eq("isDel", 2);
        queryWrapper.orderByDesc("o.createTime");
        queryWrapper.createAlias("vipprice", "vipprice");
        if (ObjectUtils.isNotEmpty(orderStatus)) {
            queryWrapper.eq("orderStatus", orderStatus);
        }
        return pageList(queryWrapper);
    }

    /**
     * 查找过期的未支付订单
     */
    public void orderJob() {
        DateTime dateTime = DateUtil.offsetHour(DateUtil.date(), -12);
        List<Order> orders = list(q().eq("orderStatus", OrderStatusEnum.unpaid.code).lt("createTime", dateTime.toString()));
        if (orders.size() > 0) {
            for (Order order : orders) {
                order.setOrderStatus(OrderStatusEnum.close);
                order.setCloseDate(DateTime.now().toDateStr());
            }
            updateBatchById(orders);
        }
    }

    /**
     * 根据用户查询对应项目的未过期订单
     */
    public Order findByUser(Long targetId, Long userId) {
        return getOne(q().eq(true, "userId", userId).eq(true, "targetId", targetId).eq(true, "isDel", 2).eq(true, "orderStatus", OrderStatusEnum.unpaid.code), false);
    }

    /**
     * 根据用户查询对应项目的未过期订单
     */
    @Override
    public Order checkUserOrder(Long targetId, Long userId) {
        return getOne(q().eq(true, "userId", userId).eq(true, "targetId", targetId).eq(true, "orderStatus", OrderStatusEnum.unpaid.code), false);
    }

    /**
     * 7日销售量
     */
    public List<EntityMap> getSevenSale() {
        return baseMapper.getSevenSale();
    }

    /**
     * 每月销售量
     */
    public List<EntityMap> getYearSale(String createTime) {
        EntityMap map = new EntityMap();
        map.put("createTime", createTime);
        return baseMapper.getYearSale(map);
    }

    /**
     * 获取销售统计
     */
    @Override
    public List<String> getCharge(String beginTime, String endTime){
        List<String> list = new ArrayList<>();
        QueryWrapper eq = new QueryWrapper<Order>();
        //今日订单合计
        eq.select("IFNULL(SUM(if(orderEntity = 'OT_STUDY',orderAmount,0)),0) OT_STUDY," +
            "IFNULL(SUM(if(orderEntity = 'OT_VIP',orderAmount,0)),0) OT_VIP," +
            "IFNULL(SUM(if(orderEntity = 'OT_TOP',orderAmount,0)),0) OT_TOP," +
            "IFNULL(SUM(if(orderEntity = 'OT_COURSE',orderAmount,0)),0) OT_COURSE," +
            "IFNULL(SUM(if(orderEntity = 'OT_APPRAISAL',orderAmount,0)),0) OT_APPRAISAL," +
            "IFNULL(SUM(if(orderEntity = 'OT_LIVE',orderAmount,0)),0) OT_LIVE," +
            "IFNULL(SUM(if(orderEntity = 'OT_OFFCOURSE',orderAmount,0)),0) OT_OFFCOURSE," +
            "IFNULL(SUM(if(orderEntity = 'OT-EXAM',orderAmount,0)),0) EXAM," +
            "IFNULL(SUM(if(orderEntity = 'OT_STUDY',orderAmount,0)),0) OT_STUDY");
        eq.eq("orderStatus", OrderStatusEnum.finish.code);
        if(ObjectUtils.isNotEmpty(beginTime) && ObjectUtils.isNotEmpty(endTime)){
            eq.le("createTime", endTime);//小于
            eq.ge("createTime", beginTime);//大于
        }
        Map<String, Object> orderMap = getMap(eq);
        list.add(orderMap.get("OT_TOP").toString());
        list.add(orderMap.get("OT_OFFCOURSE").toString());
        list.add(orderMap.get("OT_LIVE").toString());
        list.add(orderMap.get("OT_APPRAISAL").toString());
        list.add(orderMap.get("OT_VIP").toString());
        list.add(orderMap.get("OT_COURSE").toString());
        list.add(orderMap.get("OT_STUDY").toString());
        list.add(orderMap.get("EXAM").toString());
        return list;
    }

    @Override
    public Boolean returnAmount(Order order) {
        //支付状态
        PayStatusEnum payStatus = order.getPayStatus();
        //未支付或已退款的不处理
        if (PayStatusEnum.refund.equals(payStatus) || PayStatusEnum.NOPAY.equals(payStatus)) {
            return false;
        }
        //支付方式
        PayTypeEnum payType = order.getPayType();
        //修改订单状态为待退款
        if (PayTypeEnum.Balance.equals(payType)) {
            order.setOrderStatus(OrderStatusEnum.unretrun);
            saveOrUpdate(order);
            //applicationContext.publishEvent(new BalanceChangeEvent(this, order.getUserId(), order.getOrderAmount(), order.getOutTradeNo()));
        }
        return null;
    }

    @Override
    public Boolean updateOrderStatus(Long orderId, OrderStatusEnum orderStatusEnum) {
        UpdateWrapper u = new UpdateWrapper();
        return update(u.set(true, "orderStatus", orderStatusEnum.code).eq(true, "id", orderId));
    }

    @Override
    public Boolean returnAmount(Long orderId, BigDecimal returnAmount, String returnDate, String reason) {
        UpdateWrapper u = new UpdateWrapper();
        return update(u.set(true, "returnAmount", returnAmount).set(true, "payStatus", PayStatusEnum.refund).set(true, "returnDate", returnDate)
            .set(true, "orderStatus", OrderStatusEnum.close).set(true, "reason", reason).eq(true, "id", orderId));
    }

    public Integer countByUser(Long userId){
        return count(q().eq(true, "userId", userId));
    }

    @Override
    public Boolean updateWxOrder(String orderTradeNo) {
        UpdateWrapper u = new UpdateWrapper();
        return update(u.set(true, "orderStatus", OrderStatusEnum.finish).set(true,"payDate", DateUtils.getDateTime()).set(true,"payStatus", PayStatusEnum.PAY).eq(true, "outTradeNo", orderTradeNo));
    }

    @Override
    public ResultBody selectOrders(PagerInfo pagerInfo, Long userId){
        CriteriaQuery queryWrapper = new CriteriaQuery<EntityMap>(pagerInfo);
        queryWrapper.select("*");
        queryWrapper.eq("orderStatus", OrderStatusEnum.finish.code);
        queryWrapper.eq("isDel", 2);
        queryWrapper.eq("isInvoice", 2);
        queryWrapper.eq("userId", userId);
        queryWrapper.orderByDesc("createTime");
        return ResultBody.success(pageList(queryWrapper));
    }

    @Override
    public EntityMap getStatistics(Long examinationId){
        CriteriaQuery cq = new CriteriaQuery<Order>();
        cq.select("IFNULL(SUM(o.orderAmount),0) amount, IFNULL(COUNT(o.id), 0) nop");
        cq.eq("exam.examinationId", examinationId);
        cq.eq("orderStatus", OrderStatusEnum.finish.code);
        cq.createAlias("exam", "exam");
        return getEntityMap(cq);
    }

}
